/**
 * 集成测试配置文件
 * Integration Test Configuration
 */

const path = require('path');

// 基础配置
const baseConfig = {
  // 应用配置
  app: {
    baseUrl: process.env.BASE_URL || 'http://localhost:3000',
    timeout: parseInt(process.env.TEST_TIMEOUT) || 30000,
    retryAttempts: parseInt(process.env.TEST_RETRY_ATTEMPTS) || 3,
    retryDelay: parseInt(process.env.TEST_RETRY_DELAY) || 1000
  },

  // 数据库配置
  database: {
    host: process.env.DB_HOST || 'localhost',
    port: parseInt(process.env.DB_PORT) || 3306,
    user: process.env.DB_USER || 'notes_user',
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME || 'personal_cloud_notes',
    connectionLimit: 10
  },

  // 测试用户配置
  testUsers: {
    admin: {
      email: process.env.TEST_ADMIN_EMAIL || 'admin@test.com',
      password: process.env.TEST_ADMIN_PASSWORD || 'TestAdmin123!',
      nickname: '测试管理员'
    },
    regularUser: {
      email: process.env.TEST_USER_EMAIL || 'testuser@test.com',
      password: process.env.TEST_USER_PASSWORD || 'TestUser123!',
      nickname: '测试用户'
    },
    loadTestUser: {
      email: process.env.LOAD_TEST_USER_EMAIL || 'loadtest@test.com',
      password: process.env.LOAD_TEST_USER_PASSWORD || 'LoadTest123!',
      nickname: '负载测试用户'
    }
  },

  // 文件上传测试配置
  fileUpload: {
    maxFileSize: 100 * 1024 * 1024, // 100MB
    maxImageSize: 5 * 1024 * 1024,  // 5MB
    maxVideoSize: 50 * 1024 * 1024, // 50MB
    maxAudioSize: 10 * 1024 * 1024, // 10MB
    allowedImageTypes: ['image/jpeg', 'image/png', 'image/webp'],
    allowedVideoTypes: ['video/mp4', 'video/webm'],
    allowedAudioTypes: ['audio/mp3', 'audio/wav'],
    testFilesDir: path.join(__dirname, 'test-files')
  },

  // 负载测试配置
  loadTest: {
    maxConcurrentUsers: parseInt(process.env.LOAD_TEST_USERS) || 50,
    testDurationSeconds: parseInt(process.env.LOAD_TEST_DURATION) || 60,
    rampUpSeconds: parseInt(process.env.LOAD_TEST_RAMP_UP) || 10,
    thinkTimeMs: parseInt(process.env.LOAD_TEST_THINK_TIME) || 1000,
    maxResponseTimeMs: parseInt(process.env.LOAD_TEST_MAX_RESPONSE_TIME) || 5000,
    errorRateThreshold: parseFloat(process.env.LOAD_TEST_ERROR_THRESHOLD) || 5.0,
    requestsPerSecondThreshold: parseFloat(process.env.LOAD_TEST_RPS_THRESHOLD) || 10.0
  },

  // 性能测试阈值
  performance: {
    maxResponseTime: {
      login: 2000,
      getNotes: 1000,
      createNote: 3000,
      updateNote: 2000,
      deleteNote: 1000,
      uploadFile: 10000,
      downloadFile: 5000,
      search: 2000
    },
    maxMemoryUsage: 85, // 百分比
    maxCpuUsage: 80,    // 百分比
    maxDiskUsage: 90    // 百分比
  },

  // 测试数据配置
  testData: {
    notes: {
      sampleTitles: [
        '测试笔记标题',
        '项目文档',
        '会议记录',
        '学习笔记',
        '工作计划',
        '技术文档',
        '产品需求',
        '设计方案'
      ],
      sampleContent: [
        '<h1>标题</h1><p>这是一个测试笔记的内容。</p>',
        '<p>包含<strong>粗体</strong>和<em>斜体</em>文本。</p>',
        '<ul><li>列表项1</li><li>列表项2</li><li>列表项3</li></ul>',
        '<blockquote>这是一个引用块。</blockquote>',
        '<p>包含链接：<a href="https://example.com">示例链接</a></p>'
      ]
    },
    files: {
      sampleNames: [
        'test-document.txt',
        'sample-image.jpg',
        'demo-video.mp4',
        'audio-file.mp3',
        'presentation.pdf',
        'spreadsheet.xlsx',
        'archive.zip'
      ]
    }
  },

  // 报告配置
  reporting: {
    outputDir: path.join(__dirname, '../reports'),
    formats: ['json', 'html', 'xml'],
    includeScreenshots: false,
    includeDetailedLogs: true,
    maxLogSize: 10 * 1024 * 1024 // 10MB
  },

  // 环境特定配置
  environments: {
    development: {
      app: {
        baseUrl: 'http://localhost:3000'
      },
      database: {
        database: 'personal_cloud_notes_dev'
      },
      loadTest: {
        maxConcurrentUsers: 10,
        testDurationSeconds: 30
      }
    },
    
    staging: {
      app: {
        baseUrl: 'https://staging.example.com'
      },
      database: {
        database: 'personal_cloud_notes_staging'
      },
      loadTest: {
        maxConcurrentUsers: 25,
        testDurationSeconds: 60
      }
    },
    
    production: {
      app: {
        baseUrl: 'https://notes.example.com'
      },
      database: {
        database: 'personal_cloud_notes'
      },
      loadTest: {
        maxConcurrentUsers: 100,
        testDurationSeconds: 300
      }
    }
  }
};

/**
 * 获取当前环境配置
 */
function getConfig() {
  const environment = process.env.NODE_ENV || 'development';
  const envConfig = baseConfig.environments[environment] || {};
  
  // 深度合并配置
  const config = JSON.parse(JSON.stringify(baseConfig));
  
  // 合并环境特定配置
  Object.keys(envConfig).forEach(key => {
    if (typeof envConfig[key] === 'object' && !Array.isArray(envConfig[key])) {
      config[key] = { ...config[key], ...envConfig[key] };
    } else {
      config[key] = envConfig[key];
    }
  });
  
  return config;
}

/**
 * 验证配置
 */
function validateConfig(config) {
  const errors = [];
  
  // 验证必需的配置项
  if (!config.app.baseUrl) {
    errors.push('app.baseUrl 是必需的');
  }
  
  if (!config.database.password) {
    errors.push('database.password 是必需的');
  }
  
  if (!config.testUsers.admin.email || !config.testUsers.admin.password) {
    errors.push('管理员测试用户凭据是必需的');
  }
  
  // 验证URL格式
  try {
    new URL(config.app.baseUrl);
  } catch (error) {
    errors.push('app.baseUrl 格式无效');
  }
  
  // 验证数值范围
  if (config.loadTest.maxConcurrentUsers < 1 || config.loadTest.maxConcurrentUsers > 1000) {
    errors.push('loadTest.maxConcurrentUsers 必须在 1-1000 之间');
  }
  
  if (config.loadTest.testDurationSeconds < 10 || config.loadTest.testDurationSeconds > 3600) {
    errors.push('loadTest.testDurationSeconds 必须在 10-3600 之间');
  }
  
  if (errors.length > 0) {
    throw new Error(`配置验证失败:\n${errors.join('\n')}`);
  }
  
  return true;
}

/**
 * 创建测试文件
 */
async function createTestFiles() {
  const fs = require('fs').promises;
  const testFilesDir = baseConfig.fileUpload.testFilesDir;
  
  try {
    await fs.mkdir(testFilesDir, { recursive: true });
    
    // 创建文本文件
    await fs.writeFile(
      path.join(testFilesDir, 'test-document.txt'),
      '这是一个测试文档文件，用于文件上传测试。\n包含中文内容和特殊字符：@#$%^&*()'
    );
    
    // 创建小型图片文件（1x1像素PNG）
    const pngData = Buffer.from([
      0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
      0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
      0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53,
      0xDE, 0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41,
      0x54, 0x08, 0x57, 0x63, 0xF8, 0x0F, 0x00, 0x00,
      0x01, 0x00, 0x01, 0x5C, 0xCD, 0x90, 0x0A, 0x00,
      0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
      0x42, 0x60, 0x82
    ]);
    
    await fs.writeFile(path.join(testFilesDir, 'test-image.png'), pngData);
    
    // 创建JSON测试数据文件
    const testData = {
      users: [
        { name: '张三', email: 'zhangsan@test.com', role: 'user' },
        { name: '李四', email: 'lisi@test.com', role: 'admin' }
      ],
      notes: [
        { title: '测试笔记1', content: '这是第一个测试笔记' },
        { title: '测试笔记2', content: '这是第二个测试笔记' }
      ]
    };
    
    await fs.writeFile(
      path.join(testFilesDir, 'test-data.json'),
      JSON.stringify(testData, null, 2)
    );
    
    console.log(`测试文件已创建在: ${testFilesDir}`);
    
  } catch (error) {
    console.error('创建测试文件失败:', error.message);
  }
}

/**
 * 清理测试文件
 */
async function cleanupTestFiles() {
  const fs = require('fs').promises;
  const testFilesDir = baseConfig.fileUpload.testFilesDir;
  
  try {
    await fs.rmdir(testFilesDir, { recursive: true });
    console.log('测试文件已清理');
  } catch (error) {
    // 忽略清理错误
  }
}

/**
 * 获取测试用户凭据
 */
function getTestUserCredentials(userType = 'regularUser') {
  const config = getConfig();
  return config.testUsers[userType] || config.testUsers.regularUser;
}

/**
 * 获取性能阈值
 */
function getPerformanceThresholds() {
  const config = getConfig();
  return config.performance;
}

/**
 * 获取负载测试配置
 */
function getLoadTestConfig() {
  const config = getConfig();
  return config.loadTest;
}

module.exports = {
  getConfig,
  validateConfig,
  createTestFiles,
  cleanupTestFiles,
  getTestUserCredentials,
  getPerformanceThresholds,
  getLoadTestConfig,
  baseConfig
};